import React, { Component } from 'react'
import { getContext } from '@/context/common/applicationContext'
import IndividualBlogCard from '@/components/viewWidget/IndividualBlogCard'
import { withRouterContext } from '@/context/router/routerContext.js'
import { get } from '@/utils/requestUtil.js'
import { Spin, message, Empty, Tag } from 'antd'
import CustomerCard2 from '@/components/viewWidget/CustomerCard2'
import CalendarWidget from '@/components/basicWidget/CalendarWidget'
import { commonQueryByCode, getDocumentsByCondition } from '@/service/document/documentService'
import ReturnTop from '@/components/viewWidget/ReturnTop'
import './index.less'

class MyBlog extends Component {

    constructor(props) {
        super(props)
        this.state = {
            loading: true,
            user: null, //当前登陆人信息
            page: 1, //当前页数
            total: 0, //数据总数
            pageSize: 10, //每页条数
            blogList: [],
            allBlogList: [],
            customerId: null,
            sortType: 'time', //排序方式，time事件 views访问量
            personClass: [], //个人博客分类标签
            blogListLoading: false, //博客列表加载
            blogAddLoading: false, //博客加载更多列表加载
            formKey: new Date().getTime() + '',
            customerCardKey: new Date().getTime() + '',
            calendarWidgetKey: new Date().getTime() + '',
            searchParam: { //查询参数
                classId: null,
                date: null
            },
            searchTags: [] //查询标签
        }
    }

    async componentDidMount() {
        await new Promise(resolve => {
            this.setState({
                customerId: this.props.routerParams.id,
                user: this.props.user
            }, resolve)
        })

        //获取个人博客标签
        let personClass = []
        if (this.state.customerId) {
            const response = await get(`/blog/get/blogClass/${this.state.customerId}`)
            if (response && response.data) personClass = response.data
        }

        //通过博客分类初始化数据
        const routerState = this.props.location.state
        if (routerState && routerState.classId) {
            let searchTags = []
            const classItem = personClass.find(item => item.id === routerState.classId)
            searchTags.push({
                type: 'class',
                value: classItem.className
            })
            await new Promise(resolve => {
                this.setState({
                    searchParam: {
                        classId: routerState.classId,
                        date: null
                    },
                    searchTags
                }, resolve)
            })
        }
        await this.searchBlog()

        if (this.state.customerId) {
            await new Promise(resolve => {
                this.setState({
                    loading: false,
                    personClass
                }, resolve)
            })
            window.addEventListener('scroll', this.handleScroll) //滚动条监视
        }
    }

    async shouldComponentUpdate(nextProps, nextState) {
        if (this.props.routerParams.id !== nextProps.routerParams.id) {
            await new Promise(resolve => {
                this.setState({
                    customerId: nextProps.routerParams.id
                }, resolve)
            })
            //初始化博客数据
            await this.searchBlog()

            //获取个人博客标签
            let personClass = []
            if (this.state.customerId) {
                const response = await get(`/blog/get/blogClass/${this.state.customerId}`)
                if (response && response.data) personClass = response.data
            }

            if (this.state.customerId) {
                await new Promise(resolve => {
                    this.setState({
                        loading: false,
                        personClass,
                        user: this.props.user,
                        formKey: new Date().getTime() + '',
                        calendarWidgetKey: new Date().getTime() + ''
                    }, resolve)
                })
            }
        }
        return true
    }

    async componentWillUnmount() {
        window.removeEventListener('scroll', this.handleScroll)
    }

    //博客删除回调函数
    deleteBlogCallBack = async () => {
        //更新列表数据
        const { customerId, page, pageSize, searchParam } = this.state
        let url = `/blog/get/blogs/${customerId}?page=${1}&size=${page * pageSize}`
        if (searchParam.classId) {
            url += `&classId=${searchParam.classId}`
        }
        if (searchParam.date) {
            url += `&date=${searchParam.date}`
        }
        const response = await get(url)
        if (response && response.data) {
            let blogList = response.data.blogs
            await this.initBlogData(blogList, response.data.total, 'refresh')
        } else {
            message.warning('博客信息获取失败！')
        }
    }

    //查询博客信息
    searchBlog = async () => {
        const { customerId, page, pageSize, searchParam } = this.state
        let url = `/blog/get/blogs/${customerId}?page=${page}&size=${pageSize}`
        if (searchParam.classId) {
            url += `&classId=${searchParam.classId}`
        }
        if (searchParam.date) {
            url += `&date=${searchParam.date}`
        }
        const response = await get(url)
        if (response && response.data) {
            let blogList = response.data.blogs
            await this.initBlogData(blogList, response.data.total)
        } else {
            message.warning('博客信息获取失败！')
        }
    }

    /**
     * 博客数据初始化
     * 该方法用于更新博客列表数据，可以根据类型添加或刷新博客列表
     * @param {Array} newBlogList 新的博客列表数据
     * @param {Number} total 博客总数
     * @param {String} type 操作类型，'add' 为添加新数据，'refresh' 为刷新数据，默认为 'add'
     */
    initBlogData = async (newBlogList, total, type = 'add') => {
        // 获取当前状态中的博客列表和所有博客列表
        let { blogList, allBlogList } = this.state
        // 根据类型决定是添加新博客还是刷新博客列表
        if (type === 'add') {
            blogList = [...blogList, ...newBlogList]
            allBlogList = [...allBlogList, ...newBlogList]
        } else if (type === 'refresh') {
            blogList = [...newBlogList]
            allBlogList = [...newBlogList]
        }
        // 获取当前的排序类型
        const { sortType } = this.state
        // 调用排序方法对博客列表进行排序
        this.sortBlog(blogList, sortType)
        // 使用 Promise 以便在状态更新后继续执行异步操作
        await new Promise(resolve => {
            // 更新组件状态
            this.setState({
                total: total,
                allBlogList,
                blogList,
                blogAddLoading: false,
                blogListLoading: false
            }, resolve)
        })
    }

    //博客排序
    sortBlog = (blogList, sortType) => {
        if (sortType === 'time') {
            return blogList.sort((a, b) => a.createTime > b.createTime ? -1 : a.createTime < b.createTime ? 1 : 0)
        } else if (sortType === 'views') {
            return blogList.sort((a, b) => a.views > b.views ? -1 : a.views < b.views ? 1 : 0)
        }
    }

    /**
     * 根据个人博客分类id查询下属博客信息
     * @param {*} classId 博客分类id
     * @return blogList
     */
    getBlogListInBlogClass = async (classId) => {
        let blogList = []
        const searchFactory = [
            {
                fieldName: 'classId',
                fieldValue: classId,
                operate: 'eq',
            },
            {
                fieldName: 'customerId',
                fieldValue: this.state.customerId,
                operate: 'eq'
            }
        ]
        //当前登陆人与博客主人不是同一个人
        if (this.state.customerId !== this.state.user.id) {
            searchFactory.push({
                fieldName: 'state',
                fieldValue: '已发布',
                operate: 'eq',
            })
        }
        const response = await commonQueryByCode({
            commandCode: 'getBlogListInBlogClass',
            searchFactory
        })
        if (response && response.data && response.data.documents) {
            blogList = response.data.documents.map(item => {
                return item.content
            })
        }
        return blogList
    }

    /**
     * 根据日期匹配最后修改时间查询博客信息
     * @param {*} alterTime 最后修改时间
     * @return blogList
     */
    getBlogListByCreateTime = async (createTime) => {
        let blogList = []
        const searchFactory = [
            {
                fieldName: 'createTime',
                fieldValue: createTime,
                operate: 'like',
            },
            {
                fieldName: 'customerId',
                fieldValue: this.state.customerId,
                operate: 'eq'
            }
        ]
        //当前登陆人与博客主人不是同一个人
        if (this.state.customerId !== this.state.user.id) {
            searchFactory.push({
                fieldName: 'state',
                fieldValue: '已发布',
                operate: 'eq',
            })
        }
        const response = await getDocumentsByCondition({
            serviceName: 'blog',
            collectionName: 'blog_basic_info',
            searchFactory
        })
        if (response && response.data) {
            blogList = response.data.map(item => {
                return item.content
            })
        }
        return blogList
    }

    //滚动条滚动事件
    handleScroll = async () => {
        const { blogList, total, page, blogAddLoading } = this.state
        //滚动条到底部，触发加载更多事件
        if (document.documentElement.scrollTop + document.documentElement.clientHeight >= document.documentElement.scrollHeight - 10) {
            // if (document.documentElement.scrollTop + window.innerHeight >= document.documentElement.scrollHeight - 10) {
            if (blogList.length < total && !blogAddLoading) { //未全部加载
                let newPage = page + 1
                await new Promise(resolve => {
                    this.setState({
                        page: newPage,
                        blogAddLoading: true
                    }, resolve)
                })
                if (this.state.blogAddLoading === true) {
                    await this.searchBlog()
                }
            }
        }
    }

    //获取个人的创作日期集合
    getWriteDateList = async () => {
        let makeDateList = []
        const response = await commonQueryByCode({
            commandCode: 'getWriteDateListByCustId',
            kvMap: {
                customerId: this.state.customerId
            }
        })

        if (response && response.code === 200) {
            (response.data.documents || []).forEach(item => {
                if (item.content.state === '已发布' || (item.content.state !== '已发布' && this.state.customerId === this.props.user.id)) {
                    makeDateList.push(item.content.createTime.substring(0, 10))
                }
            })
        }
        return makeDateList
    }

    /**
     * 查询标签关闭回调
     * @param {String} type class|date
     */
    searchTagCloseHandler = async (type) => {
        let { searchTags, searchParam } = this.state
        searchTags = searchTags.filter(ele => ele.type !== type)
        if (type === 'date') searchParam.date = null
        else if (type === 'class') searchParam.classId = null
        await new Promise((resolve) => {
            this.setState({
                searchTags,
                searchParam,
                blogListLoading: true,
                blogList: [],
                allBlogList: [],
                page: 1
            }, resolve)
        })
        await this.searchBlog()
    }

    /**
     * 查询页签添加回调
     * @param {Object} 参数 {type: 'class', id, value} | {type: 'date', value}
     */
    searchTagAddHandler = async (obj) => {
        let { searchParam, searchTags } = this.state
        searchTags = searchTags.filter(item => item.type !== obj.type)
        searchTags.push({
            type: obj.type,
            value: obj.value
        })
        if (obj.type === 'date') searchParam.date = obj.value
        else if (obj.type === 'class') searchParam.classId = obj.id
        await new Promise(resolve => {
            this.setState({
                searchParam,
                blogListLoading: true,
                blogList: [],
                allBlogList: [],
                searchTags,
                page: 1
            }, resolve)
        })
        await this.searchBlog()
    }

    render() {
        if (this.state.loading === true) return <Spin />
        return (
            <div className='myBlog-main' key={this.state.formKey}>
                <div className='myBlog-head'>
                    <CustomerCard2
                        key={this.state.customerCardKey}
                        user={this.props.user}
                        customerId={this.state.customerId}
                    ></CustomerCard2>
                </div>

                <div className='myBlog-body'>
                    <div className='myBlog-body-left'>
                        <div className='myBlog-Calendar'>
                            <CalendarWidget
                                key={this.state.calendarWidgetKey}
                                markDates={this.getWriteDateList}
                                onChange={async (value) => {
                                    await this.searchTagAddHandler({ type: 'date', value })
                                }}
                            ></CalendarWidget>
                        </div>
                        <div className='myBlog-personBlogClass'>
                            <div className='myBlog-personBlogClass-title'>
                                个人博客标签
                            </div>
                            <div className='myBlog-personBlogClass-body'>
                                {
                                    this.state.personClass.map(item => {
                                        return (
                                            <span
                                                key={item.id}
                                                onClick={async () => {
                                                    await this.searchTagAddHandler({ type: 'class', value: item.className, id: item.id })
                                                }}
                                            >{item.className}</span>
                                        )
                                    })
                                }
                            </div>
                        </div>
                    </div>
                    <div className='myBlog-body-right'>
                        <div className='myBlog-body-right-blogCard'>
                            <div className='myBlog-body-right-blogCard-header'>
                                <ul className='myBlog-body-right-blogCard-sort'>
                                    <li
                                        style={this.state.sortType === 'time' ? { marginRight: '2em', color: 'var(--font-seven)' } : { marginRight: '2em' }}
                                        onClick={async () => {
                                            const sortType = 'time'
                                            let { blogList } = this.state
                                            this.sortBlog(blogList, sortType)
                                            await new Promise(resolve => {
                                                this.setState({
                                                    sortType: 'time',
                                                    blogList
                                                }, resolve)
                                            })
                                        }}
                                    >按时间排序</li>
                                    <li
                                        style={this.state.sortType === 'views' ? { color: 'var(--font-seven)' } : null}
                                        onClick={async () => {
                                            const sortType = 'views'
                                            let { blogList } = this.state
                                            this.sortBlog(blogList, sortType)
                                            await new Promise(resolve => {
                                                this.setState({
                                                    sortType: 'views',
                                                    blogList
                                                }, resolve)
                                            })
                                        }}
                                    >按浏览量排序</li>
                                </ul>
                                {
                                    this.state.searchTags.map(item => {
                                        return (
                                            <Tag
                                                key={item.value}
                                                color={item.type === 'date' ? 'blue' : 'geekblue'}
                                                closable
                                                onClose={async () => {
                                                    await this.searchTagCloseHandler(item.type)
                                                }}
                                            >
                                                {item.value}
                                            </Tag>
                                        )
                                    })
                                }
                            </div>
                            {
                                this.state.blogListLoading === true ? <Spin style={{ margin: 20 }} /> :
                                    this.state.blogList.length > 0 ?
                                        <>
                                            {
                                                this.state.blogList.map(item => {
                                                    return (
                                                        <IndividualBlogCard
                                                            key={item.id}
                                                            style={{ marginBottom: '10px' }}
                                                            user={this.props.user}
                                                            blog={item}
                                                            deleteBlogCallBack={this.deleteBlogCallBack}
                                                        ></IndividualBlogCard>
                                                    )
                                                })
                                            }
                                            {this.state.blogAddLoading === true ? <div style={{ textAlign: 'center' }}><Spin /></div> : ''}
                                            {this.state.blogList.length === this.state.total ? <div style={{ textAlign: 'center', color: 'var(--one-font-color)' }}>已加载全部数据</div> : ''}
                                        </>
                                        : <Empty description={false}
                                            imageStyle={{ height: '200px', marginTop: '100px' }} />
                            }
                        </div>
                    </div>
                </div>
                <ReturnTop></ReturnTop>
            </div>
        )
    }
}

export default withRouterContext(getContext(MyBlog))
